package net.fdukedom.epicurus.service.interaction;

import org.jdom.Document;
import org.jdom.JDOMException;
import org.jdom.Element;
import org.jdom.output.XMLOutputter;
import org.jdom.xpath.XPath;

/**
 * 
 * @author Alexander Kirakozov
 */
public abstract class XMLHelper {
	/**
	 * Dom model of option file
	 */
	protected Document doc;

	/**
	 * Constructor
	 * 
	 * @param filePath
	 *            path to the option file
	 */
	protected XMLHelper() {
	}

	/**
	 * Returns value of element by corresponding XPath
	 * 
	 * @param xPath
	 *            xpath of element
	 * @return value of element by corresponding XPath
	 */
	protected String getElementValueByXPath(String xPath) {
		if (doc != null) {
			try {
				Element element = (Element) XPath.selectSingleNode(doc, xPath);
				if (element != null) {
					return element.getText();
				}
			} catch (JDOMException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		return null;
	}

	/**
	 * Returns element by xPath
	 * 
	 * @param xPath
	 *            xPath to element
	 * @return element
	 */
	protected Element getElementByXPath(String xPath) {
		if (doc != null) {
			try {
				return (Element) XPath.selectSingleNode(doc, xPath);
			} catch (JDOMException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		return null;
	}

	/**
	 * Sets element value by x path
	 * 
	 * @param xPath
	 *            xPath of element
	 * @param value
	 *            new value of element
	 */
	protected void setElementValueByXPath(String xPath, String value) {
		if (doc != null) {
			try {
				Element element = (Element) XPath.selectSingleNode(doc, xPath);
				if (element != null) {
					element.setText(value);
				}
			} catch (JDOMException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	/**
	 * Updates child root element if it is or adds new element otherwise
	 * 
	 * @param name
	 *            new element name
	 * @param value
	 *            new element value
	 */
	protected void updateRootChildElement(String name, String value) {
		if (doc != null) {
			Element root = doc.getRootElement();
			if (root != null) {
				try {
					Element element = (Element) XPath.selectSingleNode(root,
							name);
					if (element == null) {
						element = new Element(name);
						root.addContent(element);
					}
					element.setText(value);
				} catch (JDOMException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * Adds element to parent
	 * 
	 * @param parentXPath
	 *            parent xPath
	 * @param element
	 *            element
	 */
	protected void setElement(String parentXPath, Element element) {
		if (doc != null) {
			try {
				Element parent;
				parent = (Element) XPath.selectSingleNode(doc, parentXPath);
				parent.addContent(element);
			} catch (JDOMException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	/**
	 * Converts dom model to string
	 */
	public String toString() {
		XMLOutputter out = new XMLOutputter();
		return out.outputString(doc);
	}

	/**
	 * Creates dom model
	 * 
	 * @return true if file was loaded succesfully
	 */
	protected abstract void createDocument();
}
